﻿using SixLabors.ImageSharp;
using SixLabors.ImageSharp.Drawing.Processing;
using SixLabors.ImageSharp.PixelFormats;
using SixLabors.ImageSharp.Processing;

namespace TianYu.Core.Common.Captcha
{
    public class CaptchaService : ICaptchaService
    {
        private int Width { get; set; } = 200;
        private int Height { get; set; } = 70;
        private float FontSize { get; set; } = 45;
        public Color[] Colors { get; set; } = { Color.Black, Color.Red, Color.Blue, Color.Green, Color.Orange, Color.Brown, Color.Brown, Color.DarkBlue };

        public CaptchaService() { }

        public (string Code, string Base64) GeneratorImageCaptcha(int length, bool symbol = false)
        {
            return GeneratorCaptcha(length, symbol);
        }

        public (string Code, string Base64) GeneratorImageCaptcha(int length, int width, int height, float fontSize, bool symbol = false)
        {
            Width = width;
            Height = height;
            FontSize = fontSize;
            return GeneratorCaptcha(length, symbol);
        }
        public (string Code, byte[] Image) GeneratorImageByteCaptcha(int length, bool symbol = false)
        {
            return GeneratorByteCaptcha(length, symbol);
        }

        public (string Code, byte[] Image) GeneratorImageByteCaptcha(int length, int width, int height, float fontSize, bool symbol = false)
        {
            Width = width;
            Height = height;
            FontSize = fontSize;
            return GeneratorByteCaptcha(length, symbol);
        }



        private (string code, string base64) GeneratorCaptcha(int length, bool symbol)
        {
            var code = RandomHelper.NextString(length, symbol);

            var imageBytes = Generate(code);

            var base64String = Convert.ToBase64String(imageBytes);

            return (code, $"data:image/png;base64,{base64String}");
        }

        private (string code, byte[]) GeneratorByteCaptcha(int length, bool symbol)
        {
            var code = RandomHelper.NextString(length, symbol);

            var imageBytes = Generate(code);

            return (code, imageBytes);
        }

        private byte[] Generate(string code)
        {
            var r = new Random();
            var font = SixLabors.Fonts.SystemFonts.CreateFont(SixLabors.Fonts.SystemFonts.Families.First().Name, FontSize, SixLabors.Fonts.FontStyle.Bold);

            using var image = new Image<Rgba32>(Width, Height);
            image.Mutate(ctx =>
            {
                // 白底背景
                ctx.BackgroundColor(Color.White);

                // 画验证码
                for (int i = 0; i < code.Length; i++)
                {
                    ctx.DrawText(code[i].ToString()
                        , font
                        , Colors[r.Next(Colors.Length)]
                        , new PointF(20 * i + 10, r.Next(2, 12)));
                }

                // 画干扰线
                for (int i = 0; i < 6; i++)
                {
                    var pen = Pens.DashDot(Colors[r.Next(Colors.Length)], 1);
                    var p1 = new PointF(r.Next(Width), r.Next(Height));
                    var p2 = new PointF(r.Next(Width), r.Next(Height));

                    ctx.DrawLine(pen, p1, p2);
                }

                // 画噪点
                for (int i = 0; i < 60; i++)
                {
                    var pen = Pens.DashDot(Colors[r.Next(Colors.Length)], 1);
                    var p1 = new PointF(r.Next(Width), r.Next(Height));
                    var p2 = new PointF(p1.X + 1f, p1.Y + 1f);

                    ctx.DrawLine(pen, p1, p2);
                }
            });
            using var ms = new MemoryStream();
            //  格式 自定义
            image.SaveAsPng(ms);
            //image.Save(ms, new PngEncoder());
            return ms.ToArray();
        }
    }
}
